import java.util.*;

/**
 * The type Recipe.
 *
 * @author Yihan Wang
 * @date 24/06/09
 */
public class Recipe {
    private String recipeName;
    private ALSet<Ingredient> ingredients;
    private String step;
    private int ingredientSize;
    private int matchingCnt;

    ////////////////////////////////////////////////
    /**
     * The type Ingredient.
     */
    public static class Ingredient {
        private String name;
        private double quantity;
        private String unit;

        /**
         * Instantiates a new Ingredient.
         *
         * @param name     the name
         * @param quantity the quantity
         * @param unit     the unit
         */
        public Ingredient(String name, double quantity, String unit) {
            this.name = name;
            this.quantity = quantity;
            this.unit = unit;
        }

        /**
         * Gets name.
         *
         * @return the name
         */
        public String getName() {
            return name;
        }

        /**
         * Gets quantity.
         *
         * @return the quantity
         */
        public double getQuantity() {
            return quantity;
        }

        /**
         * Gets unit.
         *
         * @return the unit
         */
        public String getUnit() {
            return unit;
        }
    }

    ////////////////////////////////////////////////
    /**
     * Instantiates a new Recipe.
     */
    public Recipe() {
        this.ingredients = new ALSet<>();
        this.matchingCnt = 0;
    }

    /**
     * Instantiates a new Recipe.
     *
     * @param recipeName the recipe name
     */
    public Recipe(String recipeName) {
        this.ingredients = new ALSet<>();
        this.recipeName = recipeName;
        this.matchingCnt = 0;
    }

    ////////////////////////////////////////////////

    /**
     * Gets recipe name.
     *
     * @return the recipe name
     */
    public String getRecipeName() {
        return recipeName;
    }

    /**
     * Sets recipe name.
     *
     * @param recipeName the recipe name
     */
    public void setRecipeName(String recipeName) {
        this.recipeName = recipeName;
    }

    /**
     * Gets step.
     *
     * @return the step
     */
    public String getStep() {
        return step;
    }

    /**
     * Sets step.
     *
     * @param step the step
     */
    public void setStep(String step) {
        this.step = step;
    }

    /**
     * Gets matching cnt.
     *
     * @return the matching cnt
     */
    public int getMatchingCnt() {
        return matchingCnt;
    }

    /**
     * Sets matching cnt.
     *
     * @param matchingCnt the matching cnt
     */
    public void setMatchingCnt(int matchingCnt) {
        this.matchingCnt = matchingCnt;
    }

    /**
     * Gets ingredients.
     *
     * @return the ingredients
     */
    public ALSet<Ingredient> getIngredients() {
        return ingredients;
    }

    /**
     * Sets ingredients.
     *
     * @param ingredients the ingredients
     */
    public void setIngredients(ALSet<Ingredient> ingredients) {
        this.ingredients = ingredients;
    }

    /**
     * Gets ingredient size.
     *
     * @return the ingredient size
     */
    public int getIngredientSize() {
        return ingredientSize;
    }

    /**
     * Sets ingredient size.
     *
     * @param ingredientSize the ingredient size
     */
    public void setIngredientSize(int ingredientSize) {
        this.ingredientSize = ingredientSize;
    }

    ////////////////////////////////////////////////

    /**
     * Add ingredient.
     *
     * @param name     the name
     * @param quantity the quantity
     * @param unit     the unit
     */
    public void addIngredient(String name, double quantity, String unit) {
        this.ingredients.add(new Ingredient(name, quantity, unit));
    }

    /**
     * Cook ingredient string.
     *
     * @param fc the fc
     * @return the string
     */
    public String cookIngredient(FoodCollection fc) {
        StringBuilder result;
        this.updateMatchingCount(fc);
        if (this.foodEnoughToCook()) {
            result = new StringBuilder("You used：\n");
            for (Ingredient igt : ingredients) {
                fc.removeFood(igt.getName(), igt.getQuantity(), igt.getUnit());
                result.append(igt.getName() + " x " + igt.getQuantity() + " " + igt.getUnit() + "\n");
            }
        } else {
            result = new StringBuilder("You need to buy：\n");
            result.append(fc.checkMissingFood(this));
        }
        return result.toString();
    }

    /**
     * Food enough to cook boolean.
     *
     * @return the boolean
     */
    public boolean foodEnoughToCook() {
        updateMatchingCount(Main.fc1);
        return (matchingCnt / 100) >= ingredients.size();
    }

    /**
     * Update matching count.
     *
     * @param fc the fc
     */
    public void updateMatchingCount(FoodCollection fc) {
        int count = 0;
        for (Ingredient ingredient : ingredients) {
            for (Food food : fc.getFoodSet()) {
                if (food.getName().equalsIgnoreCase(ingredient.getName()) && food.getAmount() >= ingredient.getQuantity()) {
                    count++;
                    break;
                }
            }
        }
        if (count == ingredients.size()) {
            Random random = new Random();
            int randomNumber = random.nextInt(50) + 1;
            count = 100 * count + randomNumber * 10;
        }
        Random random = new Random();
        int randomNumber = random.nextInt(50) + 1;
        count = 100 * count + randomNumber;

        this.matchingCnt = count;
    }

    /**
     * Print recipe info string.
     *
     * @return the string
     */
    public String printRecipeInfo() {
        StringBuilder result = new StringBuilder(recipeName);
        result.append("\n\n");
        for (Ingredient igt : ingredients) {
            result.append(igt.getName() + " x " + igt.getQuantity() + " " + igt.getUnit());
            result.append("\n");
        }
        result.append("\n");
        result.append("Step: " + step);

        return result.toString();
    }

}

